﻿namespace NoIdeaIoc;

/// <summary>
/// 生命周期管理工厂
/// </summary>
public class LifeTimeFactory : IServiceProviderFactory<IServiceProvider>
{
    static LifeTimeFactory()
    {
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
    }
    Action<IContainerBuilder> onBuilderContainer;
    public LifeTimeFactory(Action<IContainerBuilder> onBuilderContainer)
    {
        this.onBuilderContainer = onBuilderContainer;
    }
    /// <summary>
    /// Creates a container builder from an <see cref="IServiceCollection" />.
    /// </summary>
    /// <param name="services">The collection of services.</param>
    /// <returns>A container builder that can be used to create an <see cref="IServiceProvider" />.</returns>
    public IServiceProvider CreateBuilder(IServiceCollection services)
    {
        // 设置表单内容限制
        return configuration(services);
    }
    /// <summary>
    /// 初始化异常处理
    /// </summary>
    void globalInit()
    {
        //AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        //TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
        //AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls13 | SecurityProtocolType.Tls;
    }
    /// <summary>
    /// 初始化NetCore模块或插件
    /// </summary>
    IServiceProvider configuration(IServiceCollection services)
    {
        globalInit();
        using (var builder = new DefaultContainerBuilder(services))
        {
            var mvcBuilders = builder.AddMvc(options =>
            {
                options.ReturnHttpNotAcceptable = true;
            });
            builder.AddControllerAssembly(assembly: Assembly.GetEntryAssembly());
            mvcBuilders.ConfigureApplicationPartManager(apm =>
            {
                foreach (var part in builder.GetAssemblyParts())
                {
                    apm.ApplicationParts.Add(part);
                }
            });
            if (onBuilderContainer != null)
            {
                onBuilderContainer(builder);
                onBuilderContainer = null;
            }
            return builder.Populate();
        }
    }
    /// <summary>
    /// Creates an <see cref="IServiceProvider" /> from the container builder.
    /// </summary>
    /// <param name="serviceProvider">The container builder.</param>
    /// <returns>An <see cref="IServiceProvider" />.</returns>
    public IServiceProvider CreateServiceProvider(IServiceProvider serviceProvider)
    {
        return serviceProvider;
    }
}